import math
from datetime import timedelta
from django.db.models import Count, Q
from django.shortcuts import render
from django.http import JsonResponse
from article.models import *
import time
from NoFish import debug
from django.core.paginator import Paginator  # 分页器
from love.models import Love
from django.core.cache import cache


# 生成随机id
def rand_id():
    t = str(time.time()).split(".")[0]  # 获取时间戳
    return t


# 跳转到发布文章页面
def article_index(request):
    return render(request, "fabu.html")


# 跳转文章详情页
def article_xq(request):
    return render(request, "wz.html")


# 文章审核页面
def xq_admin(request, aid):
    article = Article.objects.filter(aid=aid).first()
    writer = UserModel.objects.filter(uid=article.user.uid).first()
    tagList = Article_tag.objects.filter(art_id=aid).values_list('tag_id')
    tags = []
    for tag in tagList:
        tags.append(int(tag[0]) - 1)
    data = {
        'title': article.title,
        'content': article.content,
        'zhaiyao': article.zhaiyao,
        "tags": tags,  # 分类
        "writer": {
            "nickname": writer.nickname,  # 昵称
            "img": writer.img.url  # 头像
        }
    }
    return JsonResponse({"statu": True, "datas": data})


# 返回5条文章
def pageData(page_index, type_, id_="", statu=2):
    allpage = 0
    allData = None
    if type_ == "默认":
        cache_key = "default_articles"
        allData = cache.get(cache_key)  # 从缓存中获取所有数据
        # 如果缓存中没有默认的文章数据则查询数据库中的
        if allData is None:
            allData = Article.objects.filter(statu=1).order_by("-createTime")  # 按照发布时间排序
            allpage = math.ceil(allData.count() / 5)  # 向上取整，页数
            paginator = Paginator(allData, 5)  # 分页器对象，只需变一次
            cache.set("default_art_pages", allpage, 60 * 60 * 2.5)  # 设置总页数缓存
            cache.set(cache_key, paginator, 60 * 60 * 2.5)  # 设置两个半小时为缓存时间
        else:
            return allData.get_page(page_index), cache.get("default_art_pages")  # 直接返回

    elif type_ == "分类":
        allData = Article.objects.filter(article3s__tag_id=id_, statu=1).order_by("-createTime")
    elif type_ == "热度":
        # 根据点赞人数来排序
        allData = Article.objects.filter(statu=1).annotate(
            like_count=Count("article1")
        ).order_by("-like_count")
    elif type_ == "我的发布":
        allData = Article.objects.filter(user_id=id_).order_by("-createTime")
        if statu != 2:
            allData = allData.filter(statu=statu).order_by("-createTime")
    elif type_ == "关键字":
        allData = Article.objects.filter(
            (Q(title__icontains=id_) |
             Q(content__icontains=id_) |
             Q(zhaiyao__icontains=id_)) & Q(statu=1)
        ).order_by("-createTime")
    elif type_ == "管理员":
        allData = Article.objects.filter(statu=0).order_by("-createTime")
    if type_ == "管理员":
        allpage = allData.count()
    else:
        allpage = math.ceil(allData.count() / 5)  # 向上取整，页数
    paginator = Paginator(allData, 5)  # 每页5条
    return paginator.get_page(page_index), allpage


# 管理员显示
def shenheArt(request, index):
    datas, pageNums = pageData(index, "管理员")
    result = []
    for d in datas:
        temp = {
            "aid": d.aid,
            "createTime": d.createTime.strftime("%Y-%m-%d %H:%M"),
            "user": d.user.nickname,
            "title": d.title
        }
        result.append(temp)
    return JsonResponse({"statu": True, "datas": result, "pageNum": pageNums})


# 获取最近7天发布的文章数量
def getRecent(request, uid):
    try:
        cache_key = uid + "_week"
        result = cache.get(cache_key)
        # 如果缓存中有数据，则直接返回
        if result is not None:
            return JsonResponse({"statu": True, "datas": result})
        today = datetime.now().date()
        past_weeks = today - timedelta(days=7)
        counts = Article.objects.filter(user_id=uid, createTime__gte=past_weeks, createTime__lte=today) \
            .extra({"day": 'date(createTime)'}) \
            .values('day').annotate(count=Count("aid"))
        result = {str(day): 0 for day in (past_weeks + timedelta(days=n) for n in range(7))}
        cache.set(cache_key, result, 60 * 60 * 2.5)  # 设置缓存过期时间
        for count in counts:
            result[str(count['day'])] = count["count"]
        return JsonResponse({"statu": True, "datas": result})
    except Exception as e:
        debug.writeBug(e)  # 写入日志文件
        print(e)
        return JsonResponse({"statu": False})


# 获取分类的文章数量
def getFenCount(request):
    try:
        tags_count = Article_tag.objects.filter(art__statu=1).values("tag").annotate(count=Count("art"))
        dic = [0 for i in range(12)]
        for tag in tags_count:
            dic[int(tag['tag']) - 1] = tag['count']
        return JsonResponse({"statu": True, "datas": dic})
    except Exception as e:
        debug.writeBug(e)
        print(e)
        return JsonResponse({"statu": False})


# 默认分页查询
def find_ten(request):
    index = request.GET.get("index")
    uid = request.GET.get("uid")
    datas = pageData(index, "默认")
    return getDatas(datas[0], datas[1], uid)


# 分类分页查询
def find_fen(request):
    index = request.GET.get("index")
    tid = request.GET.get("tid")
    uid = request.GET.get("uid")
    datas = pageData(index, "分类", tid)
    return getDatas(datas[0], datas[1], uid)


# 用户发布的文章
def find_my(request, index, uid, statu):
    statu = int(statu)
    datas = pageData(index, "我的发布", uid, statu)
    return getDatas(datas[0], datas[1], uid)


# 按照点赞数来排序查
def find_dianzan(request):
    index = request.GET.get("index")
    uid = request.GET.get("uid")
    datas = pageData(index, "热度")
    return getDatas(datas[0], datas[1], uid)


# 关键字查询
def find_keyword(request):
    index = request.GET.get("index")
    key = request.GET.get("key")
    uid = request.GET.get("uid")
    datas = pageData(index, "关键字", key)
    return getDatas(datas[0], datas[1], uid)


# 用于将数据处理返回
def getDatas(datas, pageNum, uid):
    try:
        articles = []
        for d in datas:
            t = {
                'art_id': d.aid,  # 文章id
                "uid": d.user.uid,  # 作者id
                "uimg": d.user.img.url if d.user.img.url else "/user/default.png",
                'nickname': d.user.nickname,  # 作者昵称
                'img': d.img.url,
                'title': d.title,
                'content': d.content,
                'createTime': d.createTime,
                'loveNum': d.article1.count(),  # 点赞数量
                "pinNum":d.article2.count(),    # 评论数量
                "zhaiyao": d.zhaiyao,
                "statu":d.statu,  # 文章状态
                "islove": Love.objects.filter(lover_id=uid, art_id=d.aid).exists(),
            }
            articles.append(t)
        return JsonResponse({"statu": True, "articles": articles, "pageNum": pageNum})
    except Exception as e:
        debug.writeBug(e)
        print(e)
        return JsonResponse({'statu': False})


# 修改文章
def update_article(request):
    try:
        if request.method == "POST":
            data = request.POST
            aid = data.get("aid")  # 文章id
            title = data.get('title')  # 标题
            content = data.get("content")  # 内容
            tagList = data.get("tag_list")  # 分类列表
            zhaiyao = data.get("zhaiyao")  # 文章摘要
            article = Article.objects.filter(aid=aid).first()
            article.title = title
            article.content = content
            article.zhaiyao = zhaiyao
            article.statu = 0  # 重新审核
            # 删除之前的分类关联数据
            Article_tag.objects.filter(art_id=aid).delete()
            article.save()  # 保存
            tagList = eval(tagList)
            if type(tagList) is int:
                tagList = str(tagList)

            article_tags = [
                Article_tag(tag_id=tid, art_id=aid)
                for tid in tagList
            ]
            Article_tag.objects.bulk_create(article_tags)  # 批量添加
            return JsonResponse({"statu": True})
    except Exception as e:
        debug.writeBug(e)
        return JsonResponse({"statu": False})


# 发布文章
def add_article(request):
    try:
        if request.method == "POST":
            data = request.POST
            title = data.get('title')  # 标题
            content = data.get("content")  # 内容
            tagList = data.get("tag_list")  # 分类列表
            zhaiyao = data.get("zhaiyao")  # 文章摘要
            uid = data.get("user_id")  # 作者id
            aid = rand_id()
            article = Article(
                aid=aid,
                user_id=uid,
                title=title,
                content=content,
                zhaiyao=zhaiyao,
                statu=0
            )
            img = request.FILES.get("photo")  # 文章图像
            # 如果上传了照片
            if img:
                type_ = img.name.split(".")[-1]  # 照片类型
                img.name = aid + "." + type_  # 新照片
                article.img = img

            tagList = eval(tagList)
            if type(tagList) is int:
                tagList = [str(tagList)]
            print(tagList, type(tagList))

            article.save()  # 保存文章
            article_tags = [
                Article_tag(tag_id=tid, art_id=aid)
                for tid in tagList
            ]
            Article_tag.objects.bulk_create(article_tags)  # 批量添加
            return JsonResponse({"statu": True})
    except Exception as e:
        debug.writeBug(e)  # 写入bug
        return JsonResponse({"statu": False})


# 审核文章
def readArticle(request, aid, n):
    try:
        article = Article.objects.filter(aid=aid).first()
        article.statu = int(n)
        article.save()
        cache.delete("default_art_pages")  # 删除默认缓存页数
        cache.delete("default_articles")  # 删除默认缓存
    except Exception as e:
        debug.writeBug(e)
        return JsonResponse({"statu": False, "reason": "后台故障处理中"})


# 删除文章
def delete_art(request):
    try:
        aid = request.GET.get("aid")
        article = Article.objects.filter(aid=aid)
        if article.exists():
            cache.delete("default_art_pages")  # 删除默认缓存页数
            cache.delete("default_articles")  # 删除默认缓存
            article.first().delete()
            return JsonResponse({"statu": True})
    except Exception as e:
        debug.writeBug(e)  # 写入日志文件
        return JsonResponse({"statu": False})
